<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        body {
            background-color: rgb(227, 214, 203);
        }

        .box {
            display: flex;
            /* border: 1px solid red; */
            justify-content: space-around;
            margin: 250px auto;
            color: white;
            font-size: 20px;
            text-align: center;
        }

        .box div {
            width: 150px;
            height: 50px;
            line-height: 50px;
            border-radius: 3px;
            cursor: pointer;
            position: relative;
        }

        .box div span {
            position: absolute;
            width: 100%;
            height: 100%;
            background-color: black;
            opacity: 0.1;
            left: 0;
            top: 0;
            display: none;
        }

        .box div:hover span {
            display: block;
            background-color: black;
            width: 100%;
            height: 100%;
            opacity: 0.1;
            border-radius: 3px;
        }

        .info {
            background-color: rgb(115, 198, 226);
            width: 200px;
        }

        .success {
            background-color: yellowgreen;
            width: 200px;
        }

        .alert_div {
            background-color: orange;
            width: 200px;
        }

        .error_div {
            background-color: red;
            width: 200px;
        }

        .infotip {
            width: 40%;
            background-color: gray;
            height: 50px;
            position: absolute;
            display: flex;
            line-height: 50px;
            align-items: center;
            border-radius: 5px;
            left: calc(50% - 20%);
            top: 50px;
            display: none;
            color: #333;
        }

        .successtip {
            width: 40%;
            background-color: rgb(226, 232, 226);
            height: 50px;
            position: absolute;
            display: flex;
            line-height: 50px;
            align-items: center;
            border-radius: 5px;
            left: calc(50% - 20%);
            top: 50px;
            display: none;
            color: yellowgreen;
        }

        .alerttip {
            width: 40%;
            background-color: rgb(232, 220, 195);
            height: 50px;
            position: absolute;
            display: flex;
            line-height: 50px;
            align-items: center;
            border-radius: 5px;
            left: calc(50% - 20%);
            top: 50px;
            display: none;
            color: orange;
        }

        .errortip {
            width: 40%;
            background-color: pink;
            height: 50px;
            position: absolute;
            display: flex;
            line-height: 50px;
            align-items: center;
            border-radius: 5px;
            left: calc(50% - 20%);
            top: 50px;
            display: none;
            color: red;
        }

        .icircle {
            background-color: #333;
            border-radius: 100%;
            width: 30px;
            height: 30px;
            font-size: 30px;
            text-align: center;
            line-height: 30px;
            margin: 0 15px;
            color: white;
        }

        .scircle {
            background-color: yellowgreen;
            border-radius: 100%;
            width: 30px;
            height: 30px;
            font-size: 30px;
            text-align: center;
            line-height: 30px;
            margin: 0 15px;
            color: white;
        }

        .acircle {
            background-color: orange;
            border-radius: 100%;
            width: 30px;
            height: 30px;
            font-size: 30px;
            text-align: center;
            line-height: 30px;
            margin: 0 15px;
            color: white;
        }

        .alerticon {
            position: absolute;
            right: 20px;
            cursor: pointer;
            color: #666;
        }

        .ecircle {
            background-color: red;
            border-radius: 100%;
            width: 30px;
            height: 30px;
            font-size: 30px;
            text-align: center;
            line-height: 30px;
            margin: 0 15px;
            color: white;
        }
    </style>
</head>

<body>

    <div class="box">
        <div class="info">信息提醒<span class="isp"></span></div>
        <div class="success">成功提示<span class="ssp"></span></div>
        <div class="alert_div">警告提示<span class="asp"></span></div>
        <div class="error_div">失败提示<span class="esp"></span></div>
    </div>
    <div class="tipsbox">
        <div class="infotip">
            <div class="icircle">!</div>
            信息提醒
        </div>
        <div class="successtip">
            <div class="scircle">√</div>
            成功
        </div>
        <div class="alerttip">
            <div class="acircle">!</div>
            警告提示
            <div class="alerticon">×</div>
        </div>
        <div class="errortip">
            <div class="ecircle">×</div>
            失败提示
        </div>
    </div>

    <script>
        const box = document.querySelector('.box')
        const infotip = document.querySelector('.infotip')
        const successtip = document.querySelector('.successtip')
        const alerttip = document.querySelector('.alerttip')
        const alericon = document.querySelector('.alerticon')
        const errortip = document.querySelector('.errortip')
        const sparr = document.querySelectorAll('.box span')
        let time = null
        let flag = true

        onclick = function () {
            if(flag){
                sparr.forEach(val => {
                    val.style = ''
                    val.parentNode.style = ''
                })
            }
        }

        box.onclick = function (e) {
            e.stopPropagation()
            if(flag){
                sparr.forEach(val => {
                    val.style = ''
                    val.parentNode.style = ''
                })
                if (e.target.className == 'isp') {
                    changeStyle(e)
                    new Message({
                        text: '信息提醒',
                        type: 'info'
                    })
                }
                if (e.target.className == 'ssp') {
                    changeStyle(e)
                    new Message({
                        text: '成功提示',
                        type: 'success'
                    })
                }
                if (e.target.className == 'asp') {
                    changeStyle(e)
                    new Message({
                        text: '警告提示',//
                        type: 'warning',
                        duration: 0,
                        showClose: true,
                        center: true,//
                        onClose: function () {
                            alert('知道了')
                        }
                    })
                }
                if (e.target.className == 'esp') {
                    changeStyle(e)
                    new Message({
                        text: '失败提示',
                        type: 'error'
                    })
                }
            }
        }

        class Message {
            constructor(obj) {
                this.text = obj.text // 
                this.type = obj.type || 'info'
                this.duration = obj.duration || 2000
                this.showClose = obj.showClose || false
                this.center = obj.center || false
                this.onClose = obj.onClose

                if(flag){
                    this.align()
                    flag = false
                }
            }

            align() {
                switch (this.type) {
                    case 'info':
                        infotip.style.display = 'flex'
                        move(infotip, { top: 150 })
                        clearTimeout(time)
                        time = setTimeout(() => {
                            infotip.style.display = 'none'
                            infotip.style.top = 50 + 'px'
                            flag = true
                        }, this.duration)
                        break;
                    case 'success':
                        successtip.style.display = 'flex'
                        move(successtip, { top: 150 })
                        clearTimeout(time)
                        time = setTimeout(() => {
                            successtip.style.display = 'none'
                            successtip.style.top = 50 + 'px'
                            flag = true
                        }, this.duration)
                        break;

                    case 'warning':
                        if (this.duration !== 2000) {
                            clearTimeout(time)
                            time = setTimeout(() => {
                                alerttip.style.display = 'none'
                                alerttip.style.top = 50 + 'px'
                            }, this.duration)
                        }
                        const that = this
                        alerttip.style.display = 'flex'
                        move(alerttip, { top: 150 })


                        alericon.onclick = function () {
                            that.onClose()
                            alerttip.style.display = 'none'
                            alerttip.style.top = 50 + 'px'
                            flag = true
                        }
                        break

                    case 'error':
                        errortip.style.display = 'flex'
                        move(errortip, { top: 150 })
                        clearTimeout(time)
                        time = setTimeout(() => {
                            errortip.style.display = 'none'
                            errortip.style.top = 50 + 'px'
                            flag = true
                        }, this.duration)
                        break;
                }
            }

        }

        function changeStyle(e) {
            e.target.parentNode.style.border = '2px solid black'
            e.target.parentNode.style.width = '146px'
            e.target.parentNode.style.height = '46px'
            e.target.parentNode.style.lineHeight = '46px'
            e.target.style.display = 'block'
        }


        function move(ele, obj) {
            clearInterval(ele.t);
            ele.t = setInterval(() => {
                for (let i in obj) {
                    const now = parseInt(getComputedStyle(ele)[i]);
                    let speed = (obj[i] - now) / 20;//150 obj[i]  now 50 100/20=5 150-55/20 
                    //4.75 4.5 4.25 4
                    speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
                    ele.style[i] = now + speed + "px";//50 + 5 55 60 65 70 74
                    if(now == obj[i]){
                        clearInterval(ele.t)
                    }
                }
            }, 16)
        }
    </script>



</body>

</html>